#include"threadPool.h"
#include"my_header.h"
#include"worker_sql_tools.h"
#include<mysql/mysql.h>




// 去除字符串末尾的换行符
void remove_newline(char *str) {
    size_t len = strlen(str);
    if (len > 0 && str[len - 1] == '\n') {
        str[len - 1] = '\0';
    }
}


void *threadFunc(void*argc){
    threadPool_t*pthreadPool=(threadPool_t*)argc;
    while(1){
        //加锁
        pthread_mutex_lock(&pthreadPool->mutex);
        while(pthreadPool->taskQueue.queueSize==0&&pthreadPool->exitFlag==0){
            pthread_cond_wait(&pthreadPool->cond,&pthreadPool->mutex);
            DEBUG_PRINT("I am a worker,I am in condtion wait\n");
        }
        //醒来第一件事是看看是否要结束
        if(pthreadPool->exitFlag==1){
            DEBUG_PRINT("I am a worker,I am going to exit\n");
            pthread_mutex_unlock(&pthreadPool->mutex);
            break;
        }
        int netfd=pthreadPool->taskQueue.pFront->netfd;
        //取出netfd后在验证密码
        DEBUG_PRINT("I am a worker,I got a netfd=%d\n",netfd);
        deQueue(&pthreadPool->taskQueue);
        DEBUG_PRINT("I am a worker,I recvice a task,\n");
        pthread_mutex_unlock(&pthreadPool->mutex);
        LOG("worker verdify thepassword");

        //注册或登入阶段
        char mode[4];//判断是登入还是注册
        char salt[21];//判断是登入还是注册
        char username[64];
        char cryptograph[107]={0};
        int correct=0;
        my_init_db();

        while(!correct){
            char buf[]="welcome to networkDisk! (1 for register,2 for login)";
            sendMsg(netfd,buf);
            memset(mode,0,sizeof(mode));
            int sret=recvMsg(netfd,mode);
            if(sret==0){
                //对方断开连接
                LOG("Worker disconnect");
                DEBUG_PRINT("I am a worker,the client disconnect\n");
                break;
            }
            remove_newline(mode);
            // 打印接收到的模式请求
            DEBUG_PRINT("Received mode: '%s', length: %zu\n", mode, strlen(mode));
            if(strcmp(mode,"1")==0){
                //进入注册模式
                sendMsg(netfd,"Start registering your account,please write your name");
                sret=recvMsg(netfd,username);//接收用户名
                if(sret==0){
                    //对方断开连接
                    LOG("Worker disconnect");
                    DEBUG_PRINT("I am a worker,the client disconnect\n");
                    break;
                }
                LOG("clinet send a username for register");
                DEBUG_PRINT("receive username for register,username=%s",username);
                //生成一个随机盐值
                sret=generate_salt(salt);
                if(sret!=0){
                    DEBUG_PRINT("generate salt fail\n");
                    sendMsg(netfd,"server error,try later");
                }else{
                    DEBUG_PRINT("generate a salt,salt=%s\n",salt);
                    sendMsg(netfd,salt);
                }
                sendMsg(netfd,"plesae send your cryptograph");
                recvMsg(netfd,cryptograph);
                DEBUG_PRINT("receive a cryptograph from client,cryptograph=%s",cryptograph);
                LOG("receive a cryptograph from client");
                //服务端进行注册操作
                sret=user_register (conn,username,salt,cryptograph,netfd);
                continue;
            }else if(strcmp(mode,"2")==0){
                //进入登入模式
                sendMsg(netfd,"Start login in your account,please write your name");
                sret=recvMsg(netfd,username);//接收用户名
                if(sret==0){
                    //对方断开连接
                    LOG("Worker disconnect");
                    DEBUG_PRINT("I am a worker,the client disconnect\n");
                    break;
                }
                LOG("clinet send a username for register ,username");
                DEBUG_PRINT("receive username for register,username=%s",username);
                //收密文
                sendMsg(netfd,"plesae send your cryptograph");
                recvMsg(netfd,cryptograph);
                DEBUG_PRINT("receive a cryptograph from client,cryptograph=%s",cryptograph);
                LOG("receive a cryptograph from client");
                //服务端进行登录验证操作
                sret=user_login(conn,username,cryptograph,netfd);
                if(sret==0){
                    //在密码验证阶段密码正确，跳出循环
                    correct=1;
                }
                continue;
            }else{
                //用户发来无效字符
                sendMsg(netfd,"please write '1'or'2'");
                DEBUG_PRINT("The user sent invalid characters");
            }

        }

        if(correct==0){//客户在密码验证阶段断开连接
            break;
        }
        DEBUG_PRINT("worker begian to handle request\n"); 

        Canalysis_t canalysis;
        char request[128];
        DEBUG_PRINT("cur path: %s\n", getcwd(NULL, 0));
        bzero(&canalysis,sizeof(canalysis));
        canalysis.username = username;
        DEBUG_PRINT("canalysis.username is %s\n",canalysis.username);
        canalysis.mysql =conn;
        DEBUG_PRINT("begin initCanalysis\n");
        initCanalysis(&canalysis);//初始化命令结构体u
        while(1){
            bzero(request,sizeof(request));
            int sret=recvMsg(netfd,request);
            if(sret==0){
                //对方断开连接
                LOG("Worker disconnect");
                DEBUG_PRINT("I am a worker,the client disconnect\n");
                break;             
            }
            else if (sret == -1) {
                DEBUG_PRINT("recv error: %s\n", strerror(errno));
                continue;
            } else if (strlen(request) == 0) {
                //防止客户端一直发送空包过来，例如sizeof(4096)
                LOG("client send empty data");
                DEBUG_PRINT("Received empty data, closing connection\n");
                break;  // 主动断开连接
            }
            remove_newline(request);//去除换行符
            DEBUG_PRINT("Received request: '%s', length: %zu\n", request, strlen(request));
            LOG("client send a command");
            DEBUG_PRINT("current path: %s\n", getcwd(NULL, 0)); 
            sret=separationCommand(request, &canalysis);
            DEBUG_PRINT("current path: %s\n", getcwd(NULL, 0));
            //&对命令要求进行操作
            sret=canalysis.flag;
            if(sret==-1){
                sendMsg(netfd,canalysis.result);
                LOG(canalysis.result);
                DEBUG_PRINT("return clientCommand=%s\n",canalysis.result);
            }
            if(sret>=1&&sret<=5){
                //发字符串
                LOG("The client request directory information");
                DEBUG_PRINT("worker recv a request for directory information\n");
                DEBUG_PRINT("return clientCommand=%s\n",canalysis.result);
                sendMsg(netfd,canalysis.result);
            }else if(sret==6){
                LOG("The client request download a file");
                DEBUG_PRINT("worker recv a request for dowload a file\n");
                DEBUG_PRINT("filename=%s\n",canalysis.lastname);
                //发文件
                DEBUG_PRINT("current path: %s\n", getcwd(NULL, 0));
                sret=sendFile(netfd,canalysis.lastname);
                if(sret!=0){
                    DEBUG_PRINT("transfile fail\n");
                    continue;
                }
                DEBUG_PRINT("transfile success\n");
                sendMsg(netfd,"download success");
            }else if(sret==7){
                //收文件
                LOG("The client request save a file");
                DEBUG_PRINT("worker recv a request for save file\n");
                DEBUG_PRINT("filename=%s\n",canalysis.lastname);
                sret=recvFile(netfd);
                if(sret!=0){
                    DEBUG_PRINT("recvfile fail\n");
                    continue;
                }
                DEBUG_PRINT("transfile success\n");
                sendMsg(netfd,"puts success");
            }else if(sret==8){
                LOG("The client request remove a file");
                DEBUG_PRINT("The client request remove a file\n");
                sendMsg(netfd,"download success");
            }
            if(DEBUG_MODE){//在调试的时候让程序慢点运行
                sleep(3);
            }

        }
        freeCanalysis(&canalysis);
        close(netfd);
    }
}


int makeWorker(threadPool_t*pthreadPool){
    for(int i=0;i<pthreadPool->tidArr.workerNum;++i){
        pthread_create(&pthreadPool->tidArr.arr[i],NULL,threadFunc,pthreadPool);
    }
    return 0;
}
